+2000-10-26 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtkmarshal.list: add new marshallers used by the text widget
+
+ * gtk/gtktextbuffer.c (gtk_text_buffer_class_init): fix marshaller
+ types
+
+ * gtk/gtktexttagtable.c (gtk_text_tag_table_class_init): fix
+ marshaller types
+
+ * gtk/gtktextlayout.h, gtk/gtktextlayout.c, gtk/gtktextdisplay.h,
+ gtk/gtktextdisplay.c: We need to preserve Tk copyrights and
+ license on these files.
+
+ * gtk/gtktextiter.c (gtk_text_iter_backward_search): Make this
+ work.
+
+ * gtk/gtktextbtree.c (gtk_text_btree_new): init stamps to
+ runtime random number different for each tree, instead of
+ a constant I made up.
+
Thu Oct 26 07:36:16 2000 Tim Janik <timj@gtk.org>
* gtk/Makefile.am: buncha cleanups, kludged build sources
+2000-10-26 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtkmarshal.list: add new marshallers used by the text widget
+
+ * gtk/gtktextbuffer.c (gtk_text_buffer_class_init): fix marshaller
+ types
+
+ * gtk/gtktexttagtable.c (gtk_text_tag_table_class_init): fix
+ marshaller types
+
+ * gtk/gtktextlayout.h, gtk/gtktextlayout.c, gtk/gtktextdisplay.h,
+ gtk/gtktextdisplay.c: We need to preserve Tk copyrights and
+ license on these files.
+
+ * gtk/gtktextiter.c (gtk_text_iter_backward_search): Make this
+ work.
+
+ * gtk/gtktextbtree.c (gtk_text_btree_new): init stamps to
+ runtime random number different for each tree, instead of
+ a constant I made up.
+
Thu Oct 26 07:36:16 2000 Tim Janik <timj@gtk.org>
* gtk/Makefile.am: buncha cleanups, kludged build sources
+2000-10-26 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtkmarshal.list: add new marshallers used by the text widget
+
+ * gtk/gtktextbuffer.c (gtk_text_buffer_class_init): fix marshaller
+ types
+
+ * gtk/gtktexttagtable.c (gtk_text_tag_table_class_init): fix
+ marshaller types
+
+ * gtk/gtktextlayout.h, gtk/gtktextlayout.c, gtk/gtktextdisplay.h,
+ gtk/gtktextdisplay.c: We need to preserve Tk copyrights and
+ license on these files.
+
+ * gtk/gtktextiter.c (gtk_text_iter_backward_search): Make this
+ work.
+
+ * gtk/gtktextbtree.c (gtk_text_btree_new): init stamps to
+ runtime random number different for each tree, instead of
+ a constant I made up.
+
Thu Oct 26 07:36:16 2000 Tim Janik <timj@gtk.org>
* gtk/Makefile.am: buncha cleanups, kludged build sources
+2000-10-26 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtkmarshal.list: add new marshallers used by the text widget
+
+ * gtk/gtktextbuffer.c (gtk_text_buffer_class_init): fix marshaller
+ types
+
+ * gtk/gtktexttagtable.c (gtk_text_tag_table_class_init): fix
+ marshaller types
+
+ * gtk/gtktextlayout.h, gtk/gtktextlayout.c, gtk/gtktextdisplay.h,
+ gtk/gtktextdisplay.c: We need to preserve Tk copyrights and
+ license on these files.
+
+ * gtk/gtktextiter.c (gtk_text_iter_backward_search): Make this
+ work.
+
+ * gtk/gtktextbtree.c (gtk_text_btree_new): init stamps to
+ runtime random number different for each tree, instead of
+ a constant I made up.
+
Thu Oct 26 07:36:16 2000 Tim Janik <timj@gtk.org>
* gtk/Makefile.am: buncha cleanups, kludged build sources
+2000-10-26 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtkmarshal.list: add new marshallers used by the text widget
+
+ * gtk/gtktextbuffer.c (gtk_text_buffer_class_init): fix marshaller
+ types
+
+ * gtk/gtktexttagtable.c (gtk_text_tag_table_class_init): fix
+ marshaller types
+
+ * gtk/gtktextlayout.h, gtk/gtktextlayout.c, gtk/gtktextdisplay.h,
+ gtk/gtktextdisplay.c: We need to preserve Tk copyrights and
+ license on these files.
+
+ * gtk/gtktextiter.c (gtk_text_iter_backward_search): Make this
+ work.
+
+ * gtk/gtktextbtree.c (gtk_text_btree_new): init stamps to
+ runtime random number different for each tree, instead of
+ a constant I made up.
+
Thu Oct 26 07:36:16 2000 Tim Janik <timj@gtk.org>
* gtk/Makefile.am: buncha cleanups, kludged build sources
+2000-10-26 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtkmarshal.list: add new marshallers used by the text widget
+
+ * gtk/gtktextbuffer.c (gtk_text_buffer_class_init): fix marshaller
+ types
+
+ * gtk/gtktexttagtable.c (gtk_text_tag_table_class_init): fix
+ marshaller types
+
+ * gtk/gtktextlayout.h, gtk/gtktextlayout.c, gtk/gtktextdisplay.h,
+ gtk/gtktextdisplay.c: We need to preserve Tk copyrights and
+ license on these files.
+
+ * gtk/gtktextiter.c (gtk_text_iter_backward_search): Make this
+ work.
+
+ * gtk/gtktextbtree.c (gtk_text_btree_new): init stamps to
+ runtime random number different for each tree, instead of
+ a constant I made up.
+
Thu Oct 26 07:36:16 2000 Tim Janik <timj@gtk.org>
* gtk/Makefile.am: buncha cleanups, kludged build sources
+2000-10-26 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtkmarshal.list: add new marshallers used by the text widget
+
+ * gtk/gtktextbuffer.c (gtk_text_buffer_class_init): fix marshaller
+ types
+
+ * gtk/gtktexttagtable.c (gtk_text_tag_table_class_init): fix
+ marshaller types
+
+ * gtk/gtktextlayout.h, gtk/gtktextlayout.c, gtk/gtktextdisplay.h,
+ gtk/gtktextdisplay.c: We need to preserve Tk copyrights and
+ license on these files.
+
+ * gtk/gtktextiter.c (gtk_text_iter_backward_search): Make this
+ work.
+
+ * gtk/gtktextbtree.c (gtk_text_btree_new): init stamps to
+ runtime random number different for each tree, instead of
+ a constant I made up.
+
Thu Oct 26 07:36:16 2000 Tim Janik <timj@gtk.org>
* gtk/Makefile.am: buncha cleanups, kludged build sources
VOID:INT,INT,POINTER
VOID:OBJECT
VOID:POINTER
+VOID:POINTER,BOOLEAN
VOID:POINTER,INT
VOID:POINTER,INT,INT,POINTER,UINT,UINT
VOID:POINTER,INT,POINTER
VOID:POINTER,POINTER
+VOID:POINTER,POINTER,BOOLEAN
VOID:POINTER,POINTER,INT
+VOID:POINTER,POINTER,INT,BOOLEAN
VOID:POINTER,POINTER,INT,INT
VOID:POINTER,POINTER,POINTER
VOID:POINTER,POINTER,UINT,UINT
VOID:INT,INT,POINTER
VOID:OBJECT
VOID:POINTER
+VOID:POINTER,BOOLEAN
VOID:POINTER,INT
VOID:POINTER,INT,INT,POINTER,UINT,UINT
VOID:POINTER,INT,POINTER
VOID:POINTER,POINTER
+VOID:POINTER,POINTER,BOOLEAN
VOID:POINTER,POINTER,INT
+VOID:POINTER,POINTER,INT,BOOLEAN
VOID:POINTER,POINTER,INT,INT
VOID:POINTER,POINTER,POINTER
VOID:POINTER,POINTER,UINT,UINT
tree->views = NULL;
/* Set these to values that are unlikely to be found
- in random memory garbage. */
- tree->chars_changed_stamp = 49;
- tree->segments_changed_stamp = 243;
+ * in random memory garbage, and also avoid
+ * duplicates between tree instances.
+ */
+ tree->chars_changed_stamp = g_random_int ();
+ tree->segments_changed_stamp = g_random_int ();
tree->end_iter_line_stamp = tree->chars_changed_stamp - 1;
tree->end_iter_line = NULL;
GTK_RUN_LAST,
GTK_CLASS_TYPE (object_class),
GTK_SIGNAL_OFFSET (GtkTextBufferClass, insert_text),
- gtk_marshal_VOID__POINTER_POINTER_INT_INT,
+ gtk_marshal_VOID__POINTER_POINTER_INT_BOOLEAN,
GTK_TYPE_NONE,
4,
GTK_TYPE_POINTER,
GTK_RUN_LAST,
GTK_CLASS_TYPE (object_class),
GTK_SIGNAL_OFFSET (GtkTextBufferClass, delete_text),
- gtk_marshal_VOID__POINTER_POINTER_INT,
+ gtk_marshal_VOID__POINTER_POINTER_BOOLEAN,
GTK_TYPE_NONE,
3,
GTK_TYPE_POINTER,
* Copyright (c) 2000 Red Hat, Inc.
* Tk->Gtk port by Havoc Pennington
*
+ * This file can be used under your choice of two licenses, the LGPL
+ * and the original Tk license.
+ *
+ * LGPL:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Original Tk license:
*
* This software is copyrighted by the Regents of the University of
* California, Sun Microsystems, Inc., and other parties. The
* foregoing, the authors grant the U.S. Government and others acting
* in its behalf permission to use and distribute the software in
* accordance with the terms specified in this license.
- *
+ *
+ */
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "gtktextdisplay.h"
-/* GTK - The GIMP Toolkit
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+/* gtktextdisplay.c - display layed-out text
*
+ * Copyright (c) 1992-1994 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ * Copyright (c) 2000 Red Hat, Inc.
+ * Tk->Gtk port by Havoc Pennington
+ *
+ * This file can be used under your choice of two licenses, the LGPL
+ * and the original Tk license.
+ *
+ * LGPL:
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Original Tk license:
+ *
+ * This software is copyrighted by the Regents of the University of
+ * California, Sun Microsystems, Inc., and other parties. The
+ * following terms apply to all files associated with the software
+ * unless explicitly disclaimed in individual files.
+ *
+ * The authors hereby grant permission to use, copy, modify,
+ * distribute, and license this software and its documentation for any
+ * purpose, provided that existing copyright notices are retained in
+ * all copies and that this notice is included verbatim in any
+ * distributions. No written agreement, license, or royalty fee is
+ * required for any of the authorized uses. Modifications to this
+ * software may be copyrighted by their authors and need not follow
+ * the licensing terms described here, provided that the new terms are
+ * clearly indicated on the first page of each file where they apply.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY
+ * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+ * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION,
+ * OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
+ * NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
+ * AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
+ * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * GOVERNMENT USE: If you are acquiring this software on behalf of the
+ * U.S. government, the Government shall have only "Restricted Rights"
+ * in the software and related documentation as defined in the Federal
+ * Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
+ * are acquiring the software on behalf of the Department of Defense,
+ * the software shall be classified as "Commercial Computer Software"
+ * and the Government shall have only "Restricted Rights" as defined
+ * in Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the
+ * foregoing, the authors grant the U.S. Government and others acting
+ * in its behalf permission to use and distribute the software in
+ * accordance with the terms specified in this license.
+ *
*/
-
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
check_invariants(iter);
- new_line = gtk_text_line_previous(real->line);
+ new_line = gtk_text_line_previous (real->line);
offset_will_change = FALSE;
if (real->line_char_offset > 0)
{
real->line = new_line;
- adjust_line_number(real, -1);
+ adjust_line_number (real, -1);
}
else
{
/* Find first segment in line */
real->any_segment = real->line->segments;
- real->segment = gtk_text_line_byte_to_segment(real->line,
- 0, &offset);
+ real->segment = gtk_text_line_byte_to_segment (real->line,
+ 0, &offset);
g_assert(offset == 0);
- /* Note that if we are on the first line, we snap to the start
- of the first line and return TRUE, so TRUE means the
- iterator changed, not that the line changed; this is maybe
- a bit weird. I'm not sure there's an obvious right thing
- to do though.
- */
+ /* Note that if we are on the first line, we snap to the start of
+ * the first line and return TRUE, so TRUE means the iterator
+ * changed, not that the line changed; this is maybe a bit
+ * weird. I'm not sure there's an obvious right thing to do though.
+ */
- check_invariants(iter);
+ check_invariants (iter);
return TRUE;
}
g_return_val_if_fail (str != NULL, FALSE);
if (*str == '\0')
- return TRUE; /* we found the empty string */
+ {
+ /* If we can move one char, return the empty string there */
+ match = *iter;
+ if (gtk_text_iter_next_char (&match))
+ {
+ if (match_start)
+ *match_start = match;
+ if (match_end)
+ *match_end = match;
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
/* locate all lines */
return retval;
}
+static gboolean
+vectors_equal_ignoring_trailing (gchar **vec1,
+ gchar **vec2)
+{
+ /* Ignores trailing chars in vec2's last line */
+
+ gchar **i1, **i2;
+
+ i1 = vec1;
+ i2 = vec2;
+
+ while (*i1 && *i2)
+ {
+ if (strcmp (*i1, *i2) != 0)
+ {
+ if (*(i2 + 1) == NULL) /* if this is the last line */
+ {
+ gint len1 = strlen (*i1);
+ gint len2 = strlen (*i2);
+
+ if (len2 >= len1 &&
+ strncmp (*i1, *i2, len1) == 0)
+ {
+ /* We matched ignoring the trailing stuff in vec2 */
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+ else
+ {
+ return FALSE;
+ }
+ }
+ ++i1;
+ ++i2;
+ }
+
+ if (*i1 || *i2)
+ {
+ return FALSE;
+ }
+ else
+ return TRUE;
+}
+
+typedef struct _LinesWindow LinesWindow;
+
+struct _LinesWindow
+{
+ gint n_lines;
+ gchar **lines;
+ GtkTextIter first_line_start;
+ GtkTextIter first_line_end;
+ gboolean slice;
+ gboolean visible_only;
+};
+
+static void
+lines_window_init (LinesWindow *win,
+ const GtkTextIter *start)
+{
+ gint i;
+ GtkTextIter line_start;
+ GtkTextIter line_end;
+
+ /* If we start on line 1, there are 2 lines to search (0 and 1), so
+ * n_lines can be 2.
+ */
+ if (gtk_text_iter_is_first (start) ||
+ gtk_text_iter_get_line (start) + 1 < win->n_lines)
+ {
+ /* Already at the end, or not enough lines to match */
+ win->lines = g_new0 (gchar*, 1);
+ *win->lines = NULL;
+ return;
+ }
+
+ line_start = *start;
+ line_end = *start;
+
+ /* Move to start iter to start of line */
+ gtk_text_iter_set_line_offset (&line_start, 0);
+
+ if (gtk_text_iter_equal (&line_start, &line_end))
+ {
+ /* we were already at the start; so go back one line */
+ gtk_text_iter_backward_line (&line_start);
+ }
+
+ win->first_line_start = line_start;
+ win->first_line_end = line_end;
+
+ win->lines = g_new0 (gchar*, win->n_lines + 1);
+
+ i = win->n_lines - 1;
+ while (i >= 0)
+ {
+ gchar *line_text;
+
+ if (win->slice)
+ {
+ if (win->visible_only)
+ line_text = gtk_text_iter_get_visible_slice (&line_start, &line_end);
+ else
+ line_text = gtk_text_iter_get_slice (&line_start, &line_end);
+ }
+ else
+ {
+ if (win->visible_only)
+ line_text = gtk_text_iter_get_visible_text (&line_start, &line_end);
+ else
+ line_text = gtk_text_iter_get_text (&line_start, &line_end);
+ }
+
+ win->lines[i] = line_text;
+
+ line_end = line_start;
+ gtk_text_iter_backward_line (&line_start);
+
+ --i;
+ }
+}
+
+static gboolean
+lines_window_back (LinesWindow *win)
+{
+ GtkTextIter new_start;
+ gchar *line_text;
+
+ new_start = win->first_line_start;
+
+ if (!gtk_text_iter_backward_line (&new_start))
+ return FALSE;
+ else
+ {
+ win->first_line_start = new_start;
+ win->first_line_end = new_start;
+
+ gtk_text_iter_forward_line (&win->first_line_end);
+ }
+
+ if (win->slice)
+ {
+ if (win->visible_only)
+ line_text = gtk_text_iter_get_visible_slice (&win->first_line_start,
+ &win->first_line_end);
+ else
+ line_text = gtk_text_iter_get_slice (&win->first_line_start,
+ &win->first_line_end);
+ }
+ else
+ {
+ if (win->visible_only)
+ line_text = gtk_text_iter_get_visible_text (&win->first_line_start,
+ &win->first_line_end);
+ else
+ line_text = gtk_text_iter_get_text (&win->first_line_start,
+ &win->first_line_end);
+ }
+
+ /* Move lines to make room for first line. */
+ g_memmove (win->lines + 1, win->lines, win->n_lines * sizeof (gchar*));
+
+ *win->lines = line_text;
+
+ /* Free old last line and NULL-terminate */
+ g_free (win->lines[win->n_lines]);
+ win->lines[win->n_lines] = NULL;
+
+ return TRUE;
+}
+
+static void
+lines_window_free (LinesWindow *win)
+{
+ g_strfreev (win->lines);
+}
+
+static gchar*
+my_strrstr (const gchar *haystack,
+ const gchar *needle)
+{
+ /* FIXME GLib should have a nice implementation in it, this
+ * is slow-ass crap.
+ */
+
+ gint haystack_len = strlen (haystack);
+ gint needle_len = strlen (needle);
+ const gchar *needle_end = needle + needle_len;
+ const gchar *haystack_rend = haystack - 1;
+ const gchar *needle_rend = needle - 1;
+ const gchar *p;
+
+ p = haystack + haystack_len;
+ while (p != haystack)
+ {
+ const gchar *n = needle_end - 1;
+ const gchar *s = p - 1;
+ while (s != haystack_rend &&
+ n != needle_rend &&
+ *s == *n)
+ {
+ --n;
+ --s;
+ }
+
+ if (n == needle_rend)
+ return ++s;
+
+ --p;
+ }
+
+ return NULL;
+}
+
gboolean
-gtk_text_iter_backward_search (GtkTextIter *iter,
- const char *str,
- gboolean visible_only,
- gboolean slice)
+gtk_text_iter_backward_search (const GtkTextIter *iter,
+ const gchar *str,
+ gboolean visible_only,
+ gboolean slice,
+ GtkTextIter *match_start,
+ GtkTextIter *match_end)
{
+ gchar **lines = NULL;
+ gchar **l;
+ gint n_lines;
+ LinesWindow win;
+ gboolean retval = FALSE;
+
g_return_val_if_fail (iter != NULL, FALSE);
g_return_val_if_fail (str != NULL, FALSE);
+ if (*str == '\0')
+ {
+ /* If we can move one char, return the empty string there */
+ GtkTextIter match = *iter;
+
+ if (gtk_text_iter_prev_char (&match))
+ {
+ if (match_start)
+ *match_start = match;
+ if (match_end)
+ *match_end = match;
+ return TRUE;
+ }
+ else
+ return FALSE;
+ }
+
+ /* locate all lines */
+
+ lines = strbreakup (str, "\n", -1);
+
+ l = lines;
+ n_lines = 0;
+ while (*l)
+ {
+ ++n_lines;
+ ++l;
+ }
+
+ win.n_lines = n_lines;
+ win.slice = slice;
+ win.visible_only = visible_only;
+ lines_window_init (&win, iter);
+
+ if (*win.lines == NULL)
+ goto out;
+ do
+ {
+ gchar *first_line_match;
+
+ /* If there are multiple lines, the first line will
+ * end in '\n', so this will only match at the
+ * end of the first line, which is correct.
+ */
+ first_line_match = my_strrstr (*win.lines, *lines);
+
+ if (first_line_match &&
+ vectors_equal_ignoring_trailing (lines + 1, win.lines + 1))
+ {
+ /* Match! */
+ gint offset;
+ GtkTextIter next;
+
+ /* Offset to start of search string */
+ offset = g_utf8_strlen (*win.lines, first_line_match - *win.lines);
+
+ next = win.first_line_start;
+ if (match_start)
+ {
+ *match_start = next;
+ forward_chars_with_skipping (match_start, offset,
+ visible_only, !slice);
+ }
+
+ /* Go to end of search string */
+ l = lines;
+ while (*l)
+ {
+ offset += g_utf8_strlen (*l, -1);
+ ++l;
+ }
+
+ forward_chars_with_skipping (&next, offset,
+ visible_only, !slice);
+
+ if (match_end)
+ *match_end = next;
+
+ retval = TRUE;
+ goto out;
+ }
+ }
+ while (lines_window_back (&win));
+
+ out:
+ lines_window_free (&win);
+ g_strfreev (lines);
+
+ return retval;
}
/*
*/
gboolean
-gtk_text_iter_equal(const GtkTextIter *lhs, const GtkTextIter *rhs)
+gtk_text_iter_equal (const GtkTextIter *lhs,
+ const GtkTextIter *rhs)
{
GtkTextRealIter *real_lhs;
GtkTextRealIter *real_rhs;
GtkTextCharPredicate pred,
gpointer user_data);
-gboolean gtk_text_iter_forward_search (const GtkTextIter *iter,
- const gchar *str,
- gboolean visible_only,
- gboolean slice,
- GtkTextIter *match_start,
- GtkTextIter *match_end);
-
-gboolean gtk_text_iter_backward_search (GtkTextIter *iter,
- const char *str,
- gboolean visible_only,
- gboolean slice);
+gboolean gtk_text_iter_forward_search (const GtkTextIter *iter,
+ const gchar *str,
+ gboolean visible_only,
+ gboolean slice,
+ GtkTextIter *match_start,
+ GtkTextIter *match_end);
+gboolean gtk_text_iter_backward_search (const GtkTextIter *iter,
+ const gchar *str,
+ gboolean visible_only,
+ gboolean slice,
+ GtkTextIter *match_start,
+ GtkTextIter *match_end);
+
+
/*
* Comparisons
-/* gtktextlayout.c - calculate the layout of the text
+/* GTK - The GIMP Toolkit
+ * gtktextlayout.c - calculate the layout of the text
*
* Copyright (c) 1992-1994 The Regents of the University of California.
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
* Tk->Gtk port by Havoc Pennington
* Pango support by Owen Taylor
*
+ * This file can be used under your choice of two licenses, the LGPL
+ * and the original Tk license.
+ *
+ * LGPL:
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Original Tk license:
*
* This software is copyrighted by the Regents of the University of
* California, Sun Microsystems, Inc., and other parties. The
* foregoing, the authors grant the U.S. Government and others acting
* in its behalf permission to use and distribute the software in
* accordance with the terms specified in this license.
- *
+ *
+ */
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
#include "gtksignal.h"
/* GTK - The GIMP Toolkit
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ * gtktextlayout.h
*
+ * Copyright (c) 1992-1994 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ * Copyright (c) 2000 Red Hat, Inc.
+ * Tk->Gtk port by Havoc Pennington
+ * Pango support by Owen Taylor
+ *
+ * This file can be used under your choice of two licenses, the LGPL
+ * and the original Tk license.
+ *
+ * LGPL:
+ *
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * Original Tk license:
+ *
+ * This software is copyrighted by the Regents of the University of
+ * California, Sun Microsystems, Inc., and other parties. The
+ * following terms apply to all files associated with the software
+ * unless explicitly disclaimed in individual files.
+ *
+ * The authors hereby grant permission to use, copy, modify,
+ * distribute, and license this software and its documentation for any
+ * purpose, provided that existing copyright notices are retained in
+ * all copies and that this notice is included verbatim in any
+ * distributions. No written agreement, license, or royalty fee is
+ * required for any of the authorized uses. Modifications to this
+ * software may be copyrighted by their authors and need not follow
+ * the licensing terms described here, provided that the new terms are
+ * clearly indicated on the first page of each file where they apply.
+ *
+ * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY
+ * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
+ * DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION,
+ * OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND
+ * NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS,
+ * AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
+ * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * GOVERNMENT USE: If you are acquiring this software on behalf of the
+ * U.S. government, the Government shall have only "Restricted Rights"
+ * in the software and related documentation as defined in the Federal
+ * Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you
+ * are acquiring the software on behalf of the Department of Defense,
+ * the software shall be classified as "Commercial Computer Software"
+ * and the Government shall have only "Restricted Rights" as defined
+ * in Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the
+ * foregoing, the authors grant the U.S. Government and others acting
+ * in its behalf permission to use and distribute the software in
+ * accordance with the terms specified in this license.
+ *
*/
-
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
GTK_RUN_LAST,
GTK_CLASS_TYPE (object_class),
GTK_SIGNAL_OFFSET (GtkTextTagTableClass, tag_changed),
- gtk_marshal_VOID__POINTER_INT,
+ gtk_marshal_VOID__POINTER_BOOLEAN,
GTK_TYPE_NONE,
2,
GTK_TYPE_OBJECT,
gtk_adjustment_set_value (adj, val);
}
-gboolean
+static gboolean
gtk_text_view_scroll_to_mark_adjusted (GtkTextView *text_view,
GtkTextMark *mark,
gint margin,
static void buffer_search_forward (Buffer *buffer,
const char *str,
View *view);
+static void buffer_search_backward (Buffer *buffer,
+ const char *str,
+ View *view);
static View *view_from_widget (GtkWidget *widget);
}
}
+enum
+{
+ RESPONSE_FORWARD,
+ RESPONSE_BACKWARD
+};
+
static void
dialog_response_callback (GtkWidget *dialog, gint response_id, gpointer data)
{
View *view = data;
GtkTextIter start, end;
gchar *search_string;
+
+ if (response_id != RESPONSE_FORWARD &&
+ response_id != RESPONSE_BACKWARD)
+ {
+ gtk_widget_destroy (dialog);
+ return;
+ }
buffer = gtk_object_get_data (GTK_OBJECT (dialog), "buffer");
search_string = gtk_text_iter_get_text (&start, &end);
printf ("Searching for `%s'\n", search_string);
-
- buffer_search_forward (view->buffer, search_string, view);
+ if (response_id == RESPONSE_FORWARD)
+ buffer_search_forward (view->buffer, search_string, view);
+ else if (response_id == RESPONSE_BACKWARD)
+ buffer_search_backward (view->buffer, search_string, view);
+
g_free (search_string);
gtk_widget_destroy (dialog);
dialog = gtk_dialog_new_with_buttons ("Search",
GTK_WINDOW (view->window),
GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_BUTTON_CLOSE,
+ "Forward", RESPONSE_FORWARD,
+ "Backward", RESPONSE_BACKWARD,
+ GTK_STOCK_BUTTON_CANCEL,
GTK_RESPONSE_NONE, NULL);
}
static void
-buffer_search_forward (Buffer *buffer, const char *str,
- View *view)
+buffer_search (Buffer *buffer,
+ const char *str,
+ View *view,
+ gboolean forward)
{
GtkTextIter iter;
GtkTextIter start, end;
if (*str != '\0')
{
GtkTextIter match_start, match_end;
-
- while (gtk_text_iter_forward_search (&iter, str, TRUE, FALSE,
- &match_start, &match_end))
- {
- ++i;
- gtk_text_buffer_apply_tag (buffer->buffer, buffer->found_text_tag,
- &match_start, &match_end);
- iter = match_end;
+ if (forward)
+ {
+ while (gtk_text_iter_forward_search (&iter, str, TRUE, FALSE,
+ &match_start, &match_end))
+ {
+ ++i;
+ gtk_text_buffer_apply_tag (buffer->buffer, buffer->found_text_tag,
+ &match_start, &match_end);
+
+ iter = match_end;
+ }
+ }
+ else
+ {
+ while (gtk_text_iter_backward_search (&iter, str, TRUE, FALSE,
+ &match_start, &match_end))
+ {
+ ++i;
+ gtk_text_buffer_apply_tag (buffer->buffer, buffer->found_text_tag,
+ &match_start, &match_end);
+
+ iter = match_start;
+ }
}
}
gtk_widget_show (dialog);
}
+static void
+buffer_search_forward (Buffer *buffer, const char *str,
+ View *view)
+{
+ buffer_search (buffer, str, view, TRUE);
+}
+
+static void
+buffer_search_backward (Buffer *buffer, const char *str,
+ View *view)
+{
+ buffer_search (buffer, str, view, FALSE);
+}
+
static void
buffer_ref (Buffer *buffer)
{
static void buffer_search_forward (Buffer *buffer,
const char *str,
View *view);
+static void buffer_search_backward (Buffer *buffer,
+ const char *str,
+ View *view);
static View *view_from_widget (GtkWidget *widget);
}
}
+enum
+{
+ RESPONSE_FORWARD,
+ RESPONSE_BACKWARD
+};
+
static void
dialog_response_callback (GtkWidget *dialog, gint response_id, gpointer data)
{
View *view = data;
GtkTextIter start, end;
gchar *search_string;
+
+ if (response_id != RESPONSE_FORWARD &&
+ response_id != RESPONSE_BACKWARD)
+ {
+ gtk_widget_destroy (dialog);
+ return;
+ }
buffer = gtk_object_get_data (GTK_OBJECT (dialog), "buffer");
search_string = gtk_text_iter_get_text (&start, &end);
printf ("Searching for `%s'\n", search_string);
-
- buffer_search_forward (view->buffer, search_string, view);
+ if (response_id == RESPONSE_FORWARD)
+ buffer_search_forward (view->buffer, search_string, view);
+ else if (response_id == RESPONSE_BACKWARD)
+ buffer_search_backward (view->buffer, search_string, view);
+
g_free (search_string);
gtk_widget_destroy (dialog);
dialog = gtk_dialog_new_with_buttons ("Search",
GTK_WINDOW (view->window),
GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_BUTTON_CLOSE,
+ "Forward", RESPONSE_FORWARD,
+ "Backward", RESPONSE_BACKWARD,
+ GTK_STOCK_BUTTON_CANCEL,
GTK_RESPONSE_NONE, NULL);
}
static void
-buffer_search_forward (Buffer *buffer, const char *str,
- View *view)
+buffer_search (Buffer *buffer,
+ const char *str,
+ View *view,
+ gboolean forward)
{
GtkTextIter iter;
GtkTextIter start, end;
if (*str != '\0')
{
GtkTextIter match_start, match_end;
-
- while (gtk_text_iter_forward_search (&iter, str, TRUE, FALSE,
- &match_start, &match_end))
- {
- ++i;
- gtk_text_buffer_apply_tag (buffer->buffer, buffer->found_text_tag,
- &match_start, &match_end);
- iter = match_end;
+ if (forward)
+ {
+ while (gtk_text_iter_forward_search (&iter, str, TRUE, FALSE,
+ &match_start, &match_end))
+ {
+ ++i;
+ gtk_text_buffer_apply_tag (buffer->buffer, buffer->found_text_tag,
+ &match_start, &match_end);
+
+ iter = match_end;
+ }
+ }
+ else
+ {
+ while (gtk_text_iter_backward_search (&iter, str, TRUE, FALSE,
+ &match_start, &match_end))
+ {
+ ++i;
+ gtk_text_buffer_apply_tag (buffer->buffer, buffer->found_text_tag,
+ &match_start, &match_end);
+
+ iter = match_start;
+ }
}
}
gtk_widget_show (dialog);
}
+static void
+buffer_search_forward (Buffer *buffer, const char *str,
+ View *view)
+{
+ buffer_search (buffer, str, view, TRUE);
+}
+
+static void
+buffer_search_backward (Buffer *buffer, const char *str,
+ View *view)
+{
+ buffer_search (buffer, str, view, FALSE);
+}
+
static void
buffer_ref (Buffer *buffer)
{